package cn.com.bluemoon.daps.system.service.impl;

import cn.com.bluemoon.daps.common.domain.UserInfoHolder;
import cn.com.bluemoon.daps.system.dto.MenuDto;
import cn.com.bluemoon.daps.system.dto.SysPageDto;
import cn.com.bluemoon.daps.system.entity.DapSysMenu;
import cn.com.bluemoon.daps.system.entity.DapSysRoleMenu;
import cn.com.bluemoon.daps.system.mapper.DapSysMenuMapper;
import cn.com.bluemoon.daps.system.service.DapSysMenuService;
import cn.com.bluemoon.daps.system.service.DapSysRoleMenuService;
import cn.com.bluemoon.daps.system.vo.DapSysMenuTreeVo;
import cn.com.bluemoon.daps.system.vo.DapSysMenuVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2022-12-19
 */
@Slf4j
@Service
public class DapSysMenuServiceImpl extends ServiceImpl<DapSysMenuMapper, DapSysMenu>
        implements DapSysMenuService {

    @Autowired
    private DapSysRoleMenuService sysRoleMenuService;

    @Override
    public IPage<DapSysMenuVo> menuPage(SysPageDto pageDto){
        Page<DapSysMenuVo> page = new Page<>(pageDto.getPageNum(), pageDto.getPageSize());
        return this.getBaseMapper().findByPage(page,pageDto.getIsUse(),pageDto.getKey());

//        LambdaQueryWrapper<DapSysMenu> wrapper = new LambdaQueryWrapper<>();
//        if(Objects.nonNull(pageDto.getIsUse())){
//            wrapper.eq(DapSysMenu::getIsUse,pageDto.getIsUse());
//        }
//        if(StringUtils.isNotEmpty(pageDto.getKey())){
//            wrapper.and(w -> w.like(DapSysMenu::getName, pageDto.getKey())
//                    .or().like(DapSysMenu::getRemarks, pageDto.getKey()));
//        }
//        wrapper.orderByDesc(DapSysMenu::getUpdateTime);
//        Page<DapSysMenu> page = new Page<>(pageDto.getPageNum(), pageDto.getPageSize());
//        return this.getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public boolean saveMenu(MenuDto dto){
        String account = UserInfoHolder.getAccount();
        LocalDateTime now = LocalDateTime.now();
        DapSysMenu dapSysMenu = new DapSysMenu();
        BeanUtils.copyProperties(dto,dapSysMenu);
        //根节点的父ID为0
        if(Objects.isNull(dto.getParentId())){
            dapSysMenu.setParentId(0l);
        }
        if(Objects.isNull(dto.getId())){
            dapSysMenu.setCreateTime(now);
            dapSysMenu.setCreateUserId(account);
        }
        dapSysMenu.setUpdateTime(now);
        dapSysMenu.setUpdateUserId(account);
        return this.saveOrUpdate(dapSysMenu);
    }

    @Override
    public boolean deleteMenu(Long id){
        DapSysMenu sysMenu = this.getById(id);
        if(Objects.nonNull(sysMenu)){
            //删除子孙菜单
            List<Long> menuIdList = Lists.newArrayList();
            menuIdList.add(sysMenu.getId());
            List<DapSysMenuTreeVo> menuTree = getMenuTree(sysMenu.getParentId());
            getChildrenIds(menuTree,menuIdList);
            this.removeByIds(menuIdList);

            //级联删除角色菜单关系
            LambdaQueryWrapper<DapSysRoleMenu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(DapSysRoleMenu::getMenuId,menuIdList);
            sysRoleMenuService.remove(wrapper);
        }
        return true;
    }

    /**
     * 递归获取菜单的子孙ID
     * @param menuTreeVo
     * @param menuIdList
     */
    private void getChildrenIds(List<DapSysMenuTreeVo> menuTreeVo,List<Long> menuIdList){
        if(!CollectionUtils.isEmpty(menuTreeVo)){
            for (DapSysMenuTreeVo treeVo : menuTreeVo) {
                menuIdList.add(treeVo.getId());
                getChildrenIds(treeVo.getChildren(),menuIdList);
            }
        }
    }


    public List<DapSysMenuTreeVo> getMenuTree(Long parentId){
        List<DapSysMenu> menuList = this.list();
        List<DapSysMenuTreeVo> menuTreeVoList = menuList.stream().map(m -> {
            DapSysMenuTreeVo treeVo = new DapSysMenuTreeVo();
            BeanUtils.copyProperties(m, treeVo);
            return treeVo;
        }).collect(Collectors.toList());
        List<DapSysMenuTreeVo> sysMenuTreeVoList = convertToTreeList(menuTreeVoList, parentId);
        return sysMenuTreeVoList;
    }

    /**
     * 转树结构
     * @param menuVoList
     * @param parentId
     * @return
     */
    private List<DapSysMenuTreeVo> convertToTreeList(List<DapSysMenuTreeVo> menuVoList, Long parentId){
        Map<Long, List<DapSysMenuTreeVo>> parentIdMap = menuVoList.stream().collect(Collectors.groupingBy(DapSysMenuTreeVo::getParentId));
        //排序
        for (List<DapSysMenuTreeVo> treeVoList : parentIdMap.values()) {
            treeVoList.sort(Comparator.comparing(DapSysMenuTreeVo::getSort).thenComparing(DapSysMenuTreeVo::getName));
        }
        menuVoList.forEach(menuVo->menuVo.setChildren(parentIdMap.get(menuVo.getId())));
        return menuVoList.stream().filter(v->v.getParentId().equals(parentId)).collect(Collectors.toList());
    }
}
